package com.example.listmoudle.activity

import android.util.Log
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.LayoutManager
import kotlin.math.abs
import kotlin.math.floor

class HorizontallyLayoutManager : LayoutManager() {

    private var mScrollHorizonOffset = 0

    /**
     * 切换完整一个item的长度
     */
    private var onceCompleteScrollLength = 0

    /**
     * 第一个item的滑动偏移
     */

    private var firstChildCompleteScrollLength = -1

    /**
     * 记录屏幕可见的第一个item
     */
    private var mFirstVisiPos = 0

    /**
     * 记录屏幕可见的最后一个item
     */
    private var mLastVisiPos = 0

    /**
     * 水平方向累计偏移量
     */
    private var mHorizontalOffset = 0

    private var normalViewGap = 30

    private var childWidth = 0

    private var isAutoSelect: Boolean = true


    override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {
        return RecyclerView.LayoutParams(
            RecyclerView.LayoutParams.WRAP_CONTENT,
            RecyclerView.LayoutParams.WRAP_CONTENT
        )
    }

    override fun scrollHorizontallyBy(
        dx: Int,
        recycler: RecyclerView.Recycler,
        state: RecyclerView.State
    ): Int {
        if (dx == 0 || itemCount == 0) {
            return 0
        }
        var realDx = dx / 1.0f
        if (abs(realDx) < 0.000000001f) {
            return 0
        }
        mScrollHorizonOffset += dx

        return fill(recycler, state, dx)
    }

    private fun fill(recycler: RecyclerView.Recycler, state: RecyclerView.State, dx: Int): Int {
        var resultDelta = dx
        resultDelta = fillHorizontalLeft(recycler, state, dx)
        //回收item
        return resultDelta
    }

    private fun fillHorizontalLeft(
        recycler: RecyclerView.Recycler,
        state: RecyclerView.State,
        dx: Int
    ): Int {
        var mDx = dx
        if (dx < 0) {
            if (mHorizontalOffset < 0) {
                mDx = 0
                mHorizontalOffset = 0
            }
        }
        if (dx > 0) {
            if (mHorizontalOffset >= maxOffset()) {
                mDx = 0
                mHorizontalOffset = maxOffset()
            }
        }
        detachAndScrapAttachedViews(recycler)
        var startX = 0f
        var fraction = 0f
        var isChildLayoutLeft = true

        var tempView: View? = null
        var tempPosition = -1
        if (onceCompleteScrollLength == -1) {
            tempPosition = mFirstVisiPos
            tempView = recycler.getViewForPosition(tempPosition)
            measureChildWithMargins(tempView, 0, 0)
            childWidth = getDecoratedMeasurementHorizontal(tempView)
        }
        firstChildCompleteScrollLength = width / 2 + childWidth / 2

        if (mHorizontalOffset >= firstChildCompleteScrollLength) {
            startX = normalViewGap.toFloat()
            onceCompleteScrollLength = childWidth + normalViewGap
            mFirstVisiPos =
                (floor((abs(mHorizontalOffset) - firstChildCompleteScrollLength) / onceCompleteScrollLength.toFloat())).toInt() + 1
            fraction =
                (abs(mHorizontalOffset - firstChildCompleteScrollLength) % onceCompleteScrollLength) / (onceCompleteScrollLength * 1.0f)
        } else {
            mFirstVisiPos = 0
            startX = getMinOffset()
            onceCompleteScrollLength = firstChildCompleteScrollLength
            fraction =
                (abs(mHorizontalOffset) % onceCompleteScrollLength) / (onceCompleteScrollLength * 1.0f)
        }

        mLastVisiPos = itemCount - 1
        var normalViewOffset = onceCompleteScrollLength *fraction
        var isNormalOffsetSet = false

        for (i in mFirstVisiPos until mLastVisiPos) {
            var item: View? = null
            item = if (i == tempPosition && tempView != null) {
                tempView
            } else {
                recycler.getViewForPosition(i)
            }
            var focusPosition = abs(mHorizontalOffset) / (childWidth + normalViewGap)
            if (i <= focusPosition) {
               addView(item)
            } else {
                addView(item,0)
            }
            measureChildWithMargins(item,0,0)
        }
        return dx;

    }



private fun getMinOffset(): Float {
    if (childWidth == 0) return 0f
    return (width - childWidth) / 2f
}

private fun getDecoratedMeasurementHorizontal(tempView: View): Int {
    val params = tempView.layoutParams as RecyclerView.LayoutParams
    return getDecoratedMeasuredWidth(tempView) + params.marginStart + params.marginEnd
}

fun maxOffset(): Int {
    if (childWidth == 0 || itemCount == 0)
        return 0

    return ((childWidth + normalViewGap) * itemCount - 1)
}

override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
    detachAndScrapAttachedViews(recycler)
    var left = 0
    for (i in 0 until itemCount) {
        val view = recycler.getViewForPosition(i)
        addView(view)
        measureChildWithMargins(view, 0, 0)
        val itemWidth = getDecoratedMeasuredWidth(view)
        val itemHeight = getDecoratedMeasuredHeight(view)

        Log.i("TAG--1--", "scrollHorizontallyBy: left:$left ,itemWidth:$itemWidth")

        layoutDecoratedWithMargins(
            view,
            left,
            0,
            left + itemWidth,
            itemHeight
        )
        left += (itemWidth + 10)

    }
}


}